﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Threading;
using System.IO;
using System.Diagnostics;
using MorphemeDll;
using Util;
using System.Windows.Threading;
using AutoCompleteText;

namespace ISUM_V2
{
    /// <summary>
    /// AutoCompleteText.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class AutoCompleteText : Window
    {
        OLEDBControl dbControl = new OLEDBControl();
        IntPtr hwnd;
        
        static IntPtr lastHandle = IntPtr.Zero;
        public static int BufferSize;
        public static String BufferString;

        public AutoCompleteText()
        {
            
            this.InitializeComponent();

            citiesACB.TextFilter += FindWords;

            System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(200);
            timer.Tick += new EventHandler(timer_Tick);

            //  MyButton mybtn = new MyButton();
            //  mybtn.Location = new System.Drawing.Point(10, 10);
            //  mybtn.Visible = true;
            //  mybtn.Size =  new System.Drawing.Size(124, 35);
            ////  this.LayoutRoot.

            //    timer.Start();
            // 개체 만들기에 필요한 코드를 이 지점 아래에 삽입하십시오.
        }

        public IntPtr GetLastActive()
        {
            IntPtr curHandle = WinApi.GetForegroundWindow();
            IntPtr retHandle = IntPtr.Zero;
            try
            {
               
                if (curHandle != lastHandle)
                {
                    //Keep previous for our check
                    retHandle = lastHandle;

                    //Always set last 
                    lastHandle = curHandle;

                    if (retHandle != IntPtr.Zero)
                        return retHandle;
                }

            }catch(Exception ex)
            {

                Console.WriteLine(ex.StackTrace);
            }
            return retHandle;
        }
        public void setPosition()
        {
            try
            {
                int nDifferentX = 0, nDifferentY = 0;

                hwnd = WinApi.GetForegroundWindow();
                int processID = 0;
                int threadID = WinApi.GetWindowThreadProcessId(hwnd, out processID);

                switch (Process.GetProcessById(processID).ProcessName)
                {
                    case "Hwp":
                        nDifferentX = 20;
                        nDifferentY = 165;
                        break;

                    case "WINWORD":
                        nDifferentX = 10;
                        nDifferentY = 160;
                        break;

                    case "POWERPNT":
                        nDifferentX = 280;
                        nDifferentY = 160;
                        break;

                    case "EXCEL":
                        nDifferentX = 10;
                        nDifferentY = 180;
                        break;

                    case "notepad":
                        nDifferentX = 10;
                        nDifferentY = 60;
                        break;

                    case "JungUmGW":
                        nDifferentX = 10;
                        nDifferentY = 120;
                        break;

                    case "devenv":
                        nDifferentX = 32;
                        nDifferentY = 220;
                        break;

                    default:
                       
                        break;
                }
                Console.WriteLine("ID: {0}", Process.GetProcessById(processID).ProcessName);
                WinApi.RECT rc;
                WinApi.GetWindowRect(hwnd, out rc);

                this.Left = rc.Left + Caret.getCaretLeft() + nDifferentX;
                this.Top = rc.Top + Caret.getCaretBottom() + nDifferentY;
                this.Topmost = true;
            }catch(Exception ex)
            {

                Console.WriteLine(ex.StackTrace);
            }

        }
        void timer_Tick(object sender, EventArgs e)
        {
            //GetLastActive();



            if (!citiesACB.IsKeyboardFocusWithin)
            {


                //  Btn2.Content = count.ToString();
                int nDifferentX = 0, nDifferentY = 0;
                Console.WriteLine(Caret.getCaretLeft() + "," + Caret.getCaretBottom());

                IntPtr sss = WinApi.GetActiveWindow();
                Console.WriteLine(sss.ToString());
                // Rect rect = new Rect(0,0,0,0);
                IntPtr hwnd = WinApi.GetForegroundWindow();
                Console.WriteLine("Hwnd = " + hwnd);

                int processID = 0;
                int threadID = WinApi.GetWindowThreadProcessId(hwnd, out processID);
                Console.WriteLine("proc = {0}, thread = {1}", processID, threadID);
                switch (Process.GetProcessById(processID).ProcessName)
                {
                    case "Hwp":
                        nDifferentX = 20;
                        nDifferentY = 165;
                        break;

                    case "WINWORD":
                        nDifferentX = 10;
                        nDifferentY = 160;
                        break;

                    case "POWERPNT":
                        nDifferentX = 280;
                        nDifferentY = 160;
                        break;

                    case "EXCEL":
                        nDifferentX = 10;
                        nDifferentY = 180;
                        break;

                    case "notepad":
                        nDifferentX = 10;
                        nDifferentY = 60;
                        break;

                    case "JungUmGW":
                        nDifferentX = 10;
                        nDifferentY = 120;
                        break;

                    case "devenv":
                        nDifferentX = 32;
                        nDifferentY = 220;
                        break;

                    default:
                        break;
                }
                Console.WriteLine("ID: {0}", Process.GetProcessById(processID).ProcessName);
                WinApi.RECT rc;
                WinApi.GetWindowRect(hwnd, out rc);

                this.Left = rc.Left + Caret.getCaretLeft() + nDifferentX;
                this.Top = rc.Top + Caret.getCaretBottom() + nDifferentY;
                this.Topmost = true;
                //this.Activate();
                //citiesACB.Focus();
                //WinApi.ShowWindow(Process.GetProcessById(processID).Handle, 1);
                //WinApi.BringWindowToTop(Process.GetProcessById(processID).Handle);
                //WinApi.SetForegroundWindow(Process.GetProcessById(processID).Handle);
                // System.Windows.Forms.SendKeys.SendWait("김남일");

                Console.WriteLine(rc.Left + "," + rc.Right + ", " + rc.Top + ", " + rc.Bottom + ", ");
                //Console.WriteLine(hwnd.HandleCount + "," + hwnd.ProcessName);
            }
        }

        public bool FindWords(string search, string value)
        {
            FSSearch fs = new FSSearch();
            string result;
            result = fs.StringToJaso(value.ToLower());
            if (result.StartsWith(fs.StringToJaso(search.ToLower())))
            {

                return true;
            }
            return false;

        }
        private void MorphemeMatching()
        {
            try
            {
                MorphemeDll.Morpheme morph = new MorphemeDll.Morpheme();

                sbyte[] strInput = new sbyte[] { Convert.ToSByte('i'), Convert.ToSByte('n'), Convert.ToSByte('p'), Convert.ToSByte('u'), Convert.ToSByte('t'), Convert.ToSByte('.'), Convert.ToSByte('t'), Convert.ToSByte('x'), Convert.ToSByte('t') };
                sbyte[] strOutput = new sbyte[] { Convert.ToSByte('o'), Convert.ToSByte('u'), Convert.ToSByte('t'), Convert.ToSByte('p'), Convert.ToSByte('u'), Convert.ToSByte('t'), Convert.ToSByte('.'), Convert.ToSByte('t'), Convert.ToSByte('x'), Convert.ToSByte('t') };
                sbyte[] strOption = new sbyte[] { Convert.ToSByte('-'), Convert.ToSByte('1'), Convert.ToSByte('s') };

                unsafe
                {


                    fixed (sbyte* ptrInput = strInput)
                    {
                        fixed (sbyte* ptrOutput = strOutput)
                        {
                            fixed (sbyte* ptrOption = strOption)
                            {
                                morph.morph(4, ptrInput, ptrOutput, ptrOption);

                            }
                        }
                    }

                }
            }catch(Exception e)
            {
                Console.WriteLine(e.StackTrace);
            }
        }

        public void RealTimeStudy()
        {
            try
            {
                int tmpCount;
                tmpCount = dbControl.DBSelectCnt(citiesACB.Text);
                if (tmpCount == 0)
                {
                    dbControl.DBInsert(citiesACB.Text);
                    Console.WriteLine("항목선택 후 없을 때 DBInsert");
                }
                else
                {
                    dbControl.DBUpdate(citiesACB.Text, citiesACB.Text, tmpCount + 1);
                    Console.WriteLine("항목선택 후 있을 때 DBUpdate");
                }
                Console.WriteLine(citiesACB.Text);
            }catch(Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }
        }

        public void FileStudy(MainWindow window)
        {

            try
            {
                if (File.Exists("output.txt"))
                {
                    File.Delete("output.txt");
                    Console.WriteLine("파일있네");
                }
                else
                {
                    Console.WriteLine("파일없네");
                }

                FileProcess fileProc = new FileProcess();

                Frequency freq = new Frequency();
                string currentPath = System.Environment.CurrentDirectory;       //실행경로 임시저장하기
                string fileName = fileProc.OpenDocument(window);
                //MainWindow.change = "Main";
                //MainWindow.vm.Hide();
                FileInfo sourceFile = new FileInfo(fileName);
                if (sourceFile.Extension.Equals(".txt"))
                {

                    FileInfo copyFile = sourceFile.CopyTo(@"" + currentPath + "/input.txt", true);
                }
                else
                {

                    StreamWriter sr1 = new StreamWriter(currentPath + "/input.txt", false, System.Text.Encoding.Default);

                    OfficeFileReader objOFR = new OfficeFileReader();
                    string output = "";

                    objOFR.GetText(fileName, ref output);
                    sr1.WriteLine(output);

                    sr1.Close();
                }


                System.Environment.CurrentDirectory = currentPath;          //최초 실행경로 복원

                MorphemeMatching();             //형태소 분석 라이브러리 실행!!



                Stream s = File.OpenRead("output.txt");
                StreamReader sr = new StreamReader(s, Encoding.Default);
                string input = null;

                while ((input = sr.ReadLine()) != null)
                {
                    String[] words = input.Split('\t');
                    freq.addWord(words[1]);
                    Console.WriteLine(words[1]);
                }
                sr.Close();

                freq.view();
            }
            catch (Exception)
            {


            }
        }

        public void GetLastFocus()
        {

            IntPtr targetHwnd = WinApi.GetWindow(Process.GetCurrentProcess().MainWindowHandle, (uint)WinApi.GetWindow_Cmd.GW_HWNDNEXT);
            while (true)
            {
                IntPtr temp = WinApi.GetParent(targetHwnd);
                Console.WriteLine("temp : " + temp);
                if (temp.Equals(IntPtr.Zero)) break;
                targetHwnd = temp;
            }
            WinApi.SetForegroundWindow(targetHwnd);
        }
        public IntPtr GetLastFocusHwnd()
        {

            IntPtr targetHwnd = WinApi.GetWindow(Process.GetCurrentProcess().MainWindowHandle, (uint)WinApi.GetWindow_Cmd.GW_HWNDNEXT);
            while (true)
            {
                IntPtr temp = WinApi.GetParent(targetHwnd);
                Console.WriteLine("temp : " + temp);
                if (temp.Equals(IntPtr.Zero)) break;
                targetHwnd = temp;
            }
            return targetHwnd;
            //WinApi.SetForegroundWindow(targetHwnd);
        }
        private void Btn_Study_Click(object sender, RoutedEventArgs e)
        {
            
            citiesACB.Focus();

        }
        public void clearAutoCompleteText()
        {
            try
            {
                if (citiesACB.Dispatcher.CheckAccess())
                //<--- MYSTERY
                {
                    this.citiesACB.Text = "";
                }
                else
                {

                    citiesACB.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
                        (Action)(() =>
                        {
                            this.citiesACB.Text = "";
                        }));

                }
            }
            catch (Exception e)
            {

                Console.WriteLine(e.StackTrace);
            }
        }
        public void searchAutoComplete(String str)
        {
            try
            {
                Console.WriteLine("ingtext = " + str);
                citiesACB.IsDropDownOpen = false;

                citiesACB.Text = str;
                citiesACB.TabIndex = 0;
                citiesACB.IsDropDownOpen = true;
            }
            catch (Exception e)
            {

                Console.WriteLine(e.StackTrace);
            }

        }
        public void setFocusAutoComplete()
        {
            try
            {
                if (citiesACB.Dispatcher.CheckAccess())
                //<--- MYSTERY
                {
                    this.Activate();
                    citiesACB.Focus();

                }
                else
                {

                    citiesACB.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
                        (Action)(() =>
                        {
                            this.Activate();
                            citiesACB.Focus();
                        }));

                }
            }
            catch (Exception e)
            {

                Console.WriteLine(e.StackTrace);
            }
        }
        private void Btn_Reset_Click(object sender, RoutedEventArgs e)
        {
            dbControl.DBReset();
        }

        private void citiesACB_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                if (e.Key == Key.Return)
                {
                    RealTimeStudy();

                    WinApi.SetForegroundWindow(hwnd);
                    //GetLastFocus();
                    Console.WriteLine("citiesACB.Text = " + citiesACB.Text);
                    
                    for (int i = 0; i < BufferSize; i++)
                    {
                        WinApi.keybd_event((byte)WinApi.VirtualKeys.VK_BACK, 0, 0, 0);    // 백 스페이스
                        WinApi.keybd_event((byte)WinApi.VirtualKeys.VK_BACK, 0, 2, 0);
                    }
                    System.Windows.Forms.SendKeys.SendWait(citiesACB.Text.ToString());
                    this.citiesACB.Text = "";
                    this.Hide();

                }
                else if (e.Key == Key.Down || e.Key == Key.Up)
                {

                }
                else
                {


                    WinApi.SetForegroundWindow(hwnd);
                }
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.StackTrace);
            }
        }

        private void searchText()
        {
            try{
            if (citiesACB.Text.Length == 0)
            {
                citiesACB.ItemsSource = null;
            }
            if (citiesACB.Text.Length == 1 && citiesACB.ItemsSource == null)
            {
                if ((Convert.ToChar(citiesACB.Text.Substring(0, 1).ToString()) >= 65 &&
                    Convert.ToChar(citiesACB.Text.Substring(0, 1).ToString()) <= 90) ||
                    (Convert.ToChar(citiesACB.Text.Substring(0, 1).ToString()) >= 97 &&
                    Convert.ToChar(citiesACB.Text.Substring(0, 1).ToString()) <= 122))
                {

                    citiesACB.ItemsSource = dbControl.FSSearchEng(citiesACB.Text);

                }
                else
                {
                    citiesACB.ItemsSource = dbControl.FSSearchKor(citiesACB.Text);

                }

            }
            }catch(Exception e)
            {
                Console.WriteLine(e.StackTrace);
            }
        }
        private void citiesACB_TextChanged(object sender, System.Windows.RoutedEventArgs e)
        {
            // TODO: 여기에 구현된 이벤트 처리기를 추가하십시오.
            searchText();

        }

        private void Window_Closed(object sender, EventArgs e)
        {
            //MainWindow.autoLife = false;
        }
    }
}